package com.bed.lovewithpatientbed.config;

import com.bed.lovewithpatientbed.common.realm.OrdinaryUserRealm;
import com.bed.lovewithpatientbed.common.realm.SystemUserRealm;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author xuxiaoding
 * @version 1.0.0
 * @ClassName ShiroConfig.java
 * @Description shiro配置类, 1. 创建ShiroFilter; 2.创建SecurityManager; 3. 创建Realm;
 */
@Configuration
public class ShiroConfig {

    /**
     * @title getShiroFilterFactoryBean
     * @description 生成 ShiroFilter 并自动注入
     * @author xuxiaoding
     * @param defaultWebSecurityManager ShiroFilter
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
        // 创建 shiro 的 filter
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 给 shiroFilter 设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("authc", new LoginFormAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        Map<String, String> map = new LinkedHashMap<>();
        //anon 设置为公共资源  放行资源放在下面， 设置”/login“为公共资源，否则没法进行登录
        map.put("/login", "anon");
        //authc 请求这个资源需要认证和授权, 拦截 index.html
        // map.put("/login","anon");
        //authc 请求这个资源需要认证和授权
        map.put("/", "authc");
        // 拦截所有的静态页面
        map.put("/dist/views/**", "authc");
        map.put("/order/placeOrder", "authc");

        // 配置认证和授权规则
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);


        // 默认认证界面路径
        shiroFilterFactoryBean.setLoginUrl("/login.html");

        return shiroFilterFactoryBean;
    }

    /**
     * @title getDefaultWebSecurityManager
     * @description 生成 SecurityManager 并自动注入
     * @author xuxiaoding
     * @param realm Realm
     * @return
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager() {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        // 设置校验器
        defaultWebSecurityManager.setAuthenticator(modularRealmAuthenticator());
        // 给 SecurityManager 设置 Realm
        // defaultWebSecurityManager.setRealm(realm);
        Set<Realm> realms = new HashSet<>();
        realms.add(systemUserRealm());
        realms.add(ordinaryUserRealm());
        defaultWebSecurityManager.setRealms(realms);

        return defaultWebSecurityManager;
    }

    /**
     * @title getRealm
     * @description 创建 Realm 并自动注入，应该生成自动以的Realm
     * @author xuxiaoding
     */
    @Bean
    public ModularRealmAuthenticator modularRealmAuthenticator() {
        CustomModularRealmAuthenticator customModularRealmAuthenticator = new CustomModularRealmAuthenticator();
        return customModularRealmAuthenticator;
    }

    @Bean
    public SystemUserRealm systemUserRealm() {
        return new SystemUserRealm();
    }

    @Bean
    public OrdinaryUserRealm ordinaryUserRealm() {
        return new OrdinaryUserRealm();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Autowired DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}
